﻿using System;
using System.Configuration;
using System.Windows.Forms;
using RFIDCard;

namespace GatewayInspect
{
    public class RFIDReader
    {
        #region Singleton

        private static RFIDReader _instance;
        private static object _lock = new object();

        private RFIDReader()
        {
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            this.szPort = config.AppSettings.Settings["RFIDReaderPort"].Value;
            string strInterval = config.AppSettings.Settings["RFIDInterval"].Value;
            try
            {
                _interval = Convert.ToInt32(strInterval);
            }
            catch
            {
                _interval = 500;
            }
        }

        public static RFIDReader GetInstance()
        {
            if (_instance == null)
            {
                lock (_lock)
                {
                    if (_instance == null)
                    {
                        _instance = new RFIDReader();
                    }
                }
            }
            return _instance;
        }

        #endregion

        #region 读卡器变量

        Reader Reader = new Reader();

        public string szPort = "COM1";//串口端口
        private int _interval = 500;

        public string TID_Length = "6";

        public int m_hScanner = -1, nBaudRate = 0, OK = 0;
        public int EPC_Word;

        public byte[] IDTemp = new byte[120];
        public byte[] mask = new byte[96];
        public byte[] AccessPassWord = new byte[4];

        public int res;
        public byte connect_OK = 0;//0--no connect, 1--connected

        #endregion

        private Timer _timer;

        public delegate void AfterReadCardInfoHandler(string strTid, string strEPC);
        public event AfterReadCardInfoHandler AfterReadCardInfo;

        /// <summary>
        /// 开始读卡
        /// </summary>
        public void BeginRead()
        {
            Connect();
            if (connect_OK == 1)
            {
                if (_timer == null)
                {
                    _timer = new Timer();
                    _timer.Interval = _interval;
                    _timer.Tick += new EventHandler(_timer_Tick);
                }
                if (!_timer.Enabled)
                {
                    _timer.Enabled = true;
                }
            }
        }

        /// <summary>
        /// 停止读卡
        /// </summary>
        public void EndRead()
        {
            if (_timer != null && _timer.Enabled)
            {
                _timer.Enabled = false;
            }
            Disconnect();
        }

        /// <summary>
        /// 无对象实例需读卡(挂接AfterReadInfo事件)时停止读卡
        /// </summary>
        public void CheckHandler()
        {
            if (AfterReadCardInfo == null || AfterReadCardInfo.GetInvocationList().Length <= 0)
            {
                EndRead();
            }
        }

        /// <summary>
        /// 连接读写器
        /// </summary>
        private void Connect()
        {
            if (connect_OK == 1 && m_hScanner > 0)
            {
                return;
            }
            res = Reader.ConnectScanner(ref m_hScanner, szPort, ref nBaudRate);
            if (res != OK)
            {
                MessageBox.Show("RFID读卡器连接失败！", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }
            connect_OK = 1;//0--no connect, 1--connected
            //MessageBox.Show("Connect reader success!", "Notice", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
        }

        /// <summary>
        /// 断开读写器连接
        /// </summary>
        private void Disconnect()
        {
            if (connect_OK == 0)
                return;
            res = Reader.DisconnectScanner(m_hScanner);
            if (res != OK)
            {
                MessageBox.Show("断开RFID读卡器失败！", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }
            m_hScanner = -1;
            connect_OK = 0;
        }

        /// <summary>
        /// 循环读卡
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _timer_Tick(object sender, EventArgs e)
        {
            if (connect_OK == 0)
                return;
            int mem = 1;//0-password, 1-EPC, 2-TID, 3-user,
            int nCounter = 0, ID_len = 0;
            byte[] IDBuffer = new byte[7680];
            res = Reader.EPC1G2_ReadLabelID(m_hScanner, mem, 0, 0, mask, IDBuffer, ref nCounter, 0);
            if (res == OK && nCounter >= 1 && IDBuffer[0] <= 32)//读到多条时取第一条
            {
                string strEPC = "", strtemp = "";
                byte[] DB = new byte[128];

                EPC_Word = IDBuffer[0];
                ID_len = EPC_Word * 2;
                for (int j = 0; j < ID_len; j++)
                {
                    strtemp = IDBuffer[j + 1].ToString("X2");
                    strEPC += strtemp;
                    IDTemp[j] = IDBuffer[j + 1];
                }
                mem = 2;//读TID
                res = Reader.EPC1G2_ReadWordBlock(m_hScanner, Convert.ToByte(EPC_Word), IDTemp, Convert.ToByte(mem), Convert.ToByte(0), Convert.ToByte(TID_Length), DB, AccessPassWord, 0);
                if (res == OK)
                {
                    string strTID = "";
                    for (int i = 0; i < Convert.ToByte(TID_Length) * 2; i++)
                    {
                        strtemp = DB[i].ToString("X2");
                        strTID += strtemp;
                    }
                    if (!string.IsNullOrEmpty(strTID) && AfterReadCardInfo != null)
                    {
                        AfterReadCardInfo(strTID, strEPC);
                    }
                }
            }
        }
    }
}
